using System;
using System.Linq;
using HslCommunication.Core;
using HslCommunication.Core.Net;

namespace HslCommunication.Profinet.Omron
{
	/// <summary>
	/// 欧姆龙的Udp的数据对象
	/// </summary>
	/// <remarks>
	/// <inheritdoc cref="T:HslCommunication.Profinet.Omron.OmronFinsNet" path="remarks" />
	/// </remarks>
	public class OmronFinsUdp : NetworkUdpDeviceBase
	{
		/// <inheritdoc />
		public override string IpAddress
		{
			get
			{
				return base.IpAddress;
			}
			set
			{
				DA1 = Convert.ToByte(value.Substring(value.LastIndexOf(".") + 1));
				base.IpAddress = value;
			}
		}

		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.ICF" />
		public byte ICF
		{
			get;
			set;
		} = 128;


		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.RSV" />
		public byte RSV
		{
			get;
			private set;
		} = 0;


		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.GCT" />
		public byte GCT
		{
			get;
			set;
		} = 2;


		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.DNA" />
		public byte DNA
		{
			get;
			set;
		} = 0;


		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.DA1" />
		public byte DA1
		{
			get;
			set;
		} = 19;


		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.DA2" />
		public byte DA2
		{
			get;
			set;
		} = 0;


		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.SNA" />
		public byte SNA
		{
			get;
			set;
		} = 0;


		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.SA1" />
		public byte SA1
		{
			get;
			set;
		} = 13;


		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.SA2" />
		public byte SA2
		{
			get;
			set;
		}

		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronFinsNet.SID" />
		public byte SID
		{
			get;
			set;
		} = 0;


		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.#ctor(System.String,System.Int32)" />
		public OmronFinsUdp(string ipAddress, int port)
		{
			base.WordLength = 1;
			IpAddress = ipAddress;
			Port = port;
			base.ByteTransform = new ReverseWordTransform();
			base.ByteTransform.DataFormat = DataFormat.CDAB;
			base.ByteTransform.IsStringReverseByteWord = true;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.#ctor" />
		public OmronFinsUdp()
		{
			base.WordLength = 1;
			base.ByteTransform = new ReverseWordTransform();
			base.ByteTransform.DataFormat = DataFormat.CDAB;
			base.ByteTransform.IsStringReverseByteWord = true;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.PackCommand(System.Byte[])" />
		private byte[] PackCommand(byte[] cmd)
		{
			byte[] array = new byte[10 + cmd.Length];
			array[0] = ICF;
			array[1] = RSV;
			array[2] = GCT;
			array[3] = DNA;
			array[4] = DA1;
			array[5] = DA2;
			array[6] = SNA;
			array[7] = SA1;
			array[8] = SA2;
			array[9] = SID;
			cmd.CopyTo(array, 10);
			return array;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.BuildReadCommand(System.String,System.UInt16,System.Boolean)" />
		public OperateResult<byte[]> BuildReadCommand(string address, ushort length, bool isBit)
		{
			OperateResult<byte[]> operateResult = OmronFinsNetHelper.BuildReadCommand(address, length, isBit);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			return OperateResult.CreateSuccessResult(PackCommand(operateResult.Content));
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.BuildWriteCommand(System.String,System.Byte[],System.Boolean)" />
		public OperateResult<byte[]> BuildWriteCommand(string address, byte[] value, bool isBit)
		{
			OperateResult<byte[]> operateResult = OmronFinsNetHelper.BuildWriteWordCommand(address, value, isBit);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			return OperateResult.CreateSuccessResult(PackCommand(operateResult.Content));
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.Read(System.String,System.UInt16)" />
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			OperateResult<byte[]> operateResult = BuildReadCommand(address, length, isBit: false);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult2);
			}
			OperateResult<byte[]> operateResult3 = OmronFinsNetHelper.UdpResponseValidAnalysis(operateResult2.Content, isRead: true);
			if (!operateResult3.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult3);
			}
			return OperateResult.CreateSuccessResult(operateResult3.Content);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.Write(System.String,System.Byte[])" />
		public override OperateResult Write(string address, byte[] value)
		{
			OperateResult<byte[]> operateResult = BuildWriteCommand(address, value, isBit: false);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			OperateResult<byte[]> operateResult3 = OmronFinsNetHelper.UdpResponseValidAnalysis(operateResult2.Content, isRead: false);
			if (!operateResult3.IsSuccess)
			{
				return operateResult3;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.ReadBool(System.String,System.UInt16)" />
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			OperateResult<byte[]> operateResult = BuildReadCommand(address, length, isBit: true);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult2);
			}
			OperateResult<byte[]> operateResult3 = OmronFinsNetHelper.UdpResponseValidAnalysis(operateResult2.Content, isRead: true);
			if (!operateResult3.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult3);
			}
			return OperateResult.CreateSuccessResult(operateResult3.Content.Select((byte m) => (m != 0) ? true : false).ToArray());
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.Write(System.String,System.Boolean[])" />
		public override OperateResult Write(string address, bool[] values)
		{
			OperateResult<byte[]> operateResult = BuildWriteCommand(address, values.Select((bool m) => (byte)(m ? 1 : 0)).ToArray(), isBit: true);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			OperateResult<byte[]> operateResult3 = OmronFinsNetHelper.UdpResponseValidAnalysis(operateResult2.Content, isRead: false);
			if (!operateResult3.IsSuccess)
			{
				return operateResult3;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		public override string ToString()
		{
			return $"OmronFinsUdp[{IpAddress}:{Port}]";
		}
	}
}
